: input-filename s" input" ;
256 Constant max-bytes-line
Create line-buffer max-bytes-line 2 + allot
input-filename r/o open-file throw Value puzzle-input-handle

: not 0= ;

\ Sum all calories an elf carries.
: sum-elf-calories ( c-addr length -- ??? )
  \ Put 0 on the stack, as the initial accumulator value.
  0
  begin
    \ Read the next line from the puzzle input.
    line-buffer max-bytes-line puzzle-input-handle read-line throw  \ stack: acc length eof-flag
    swap  \ stack: acc eof-flag length
    \ Check if more than 0 characters were read as a number.
    dup 0 >  \ stack: acc eof-flag length more-than-0-chars-flag
    rot  \ stack: acc length more-than-0-chars-flag eof-flag
    \ Check that both true.
    and  \ stack: acc length flag

  while
    \ stack: acc length
    \ Put a float at the bottom for >number which requires a
    \ double to be at specific position.
    0.  \ stack: acc length 0. 0
    rot  \ stack: acc 0. 0 length
    line-buffer swap  \ stack: acc 0. 0 c-addr length
    >number  \ stack: acc the-number 0 c-addr length
    2swap  \ stack: acc c-addr' length' the-number 0
    \ convert double to one integer number (?)
    d>s  \ stack: acc c-addr' length' the-number
    \ Use the numbers here. For now only dropping them.
    -rot  \ stack: acc the-number c-addr' length'
    2drop  \ stack: acc the-number
    \ Add up the calories.
    +  \ stack: acc
  repeat
  drop ;

: rotate-4 ( u1 u2 u3 u4 -- u2 u3 u4 u1 )
  { a b c d }
  b c d a ;

: min-of-4 ( u u u u -- u )
  min min min ;

: drop-min-of-4
  .s cr ;  \ todo

: find-max ( -- u1 )
  \ Put a zero on the stack as an initial value for max.
  0
  begin puzzle-input-handle file-eof? not
  while
    sum-elf-calories
    \ If there are more than 3 calories sums, discard the
    \ lowest one.
    depth 3 > if drop-min-of-4 then
    .s cr
  repeat
  + + ;

find-max . cr

puzzle-input-handle close-file
